//
//  DZYTitleView.swift
//  DZYPageView
//
//  Created by dongzhenyu on 2017/7/6.
//  Copyright © 2017年 dongzhenyu. All rights reserved.
//

import UIKit

protocol DZYTitleViewDelegate: class {
    
    func titleView(_ titleView: DZYTitleView, targetIndex: Int)

}

//struct Location: DZYTitleViewDelegate {
//    
//    func titleView(_ titleView: DZYTitleView, targetIndex: Int) {
//        
//    }
//}
//
//enum Direction: DZYTitleViewDelegate {
//    
//    func titleView(_ titleView: DZYTitleView, targetIndex: Int) {
//        
//    }
//}


// 注意:
/**
 
 如果下面想要使用weak 修饰 那么上面DZYTitleViewDelegate 后面需要加上:NSObjectProtocol, 如果加上NSObjectProtocol 比较重量级
 那么如果还要想使用weak 可以在上面DZYTitleViewDelegate后面 加上:class 表示该协议只能被类遵守
 为什么要加上class呢 如果不加上class 那么在swift中 结构体 或者 枚举 也是可以遵守这个协议 不严谨 所有需要加上class
 */

class DZYTitleView: UIView {

    // MARK: - 属性
    weak var delegate: DZYTitleViewDelegate?
    
    fileprivate var titles: [String]
    fileprivate var style: DZYPageStyle
    fileprivate var currentIndex : Int = 0
    
    fileprivate lazy var normalRGB: (CGFloat, CGFloat, CGFloat) = self.style.normalColor.getRGBValue()
    fileprivate lazy var selectRGB: (CGFloat, CGFloat, CGFloat) = self.style.selectColor.getRGBValue()
    fileprivate lazy var deltaRGB: (CGFloat, CGFloat, CGFloat) = {
        let deltaR = self.selectRGB.0 - self.normalRGB.0
        let deltaG = self.selectRGB.1 - self.normalRGB.1
        let deltaB = self.selectRGB.2 - self.normalRGB.2
        return (deltaR, deltaG, deltaB)
    }()
    
    fileprivate lazy var bottomLine: UIView = {
        let bottomLine = UIView()
        bottomLine.backgroundColor = self.style.bottomLineColor
        return bottomLine
    }()
    
    fileprivate lazy var coverView: UIView = {
        let coverView = UIView()
        coverView.backgroundColor = self.style.coverViewColor
        coverView.alpha = self.style.coverViewAlpha
        return coverView
    }()
    
    fileprivate lazy var scrollView : UIScrollView = {
        
        let scrollView = UIScrollView(frame: self.bounds)
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.scrollsToTop = false
        return scrollView
    }()
    fileprivate lazy var titleLabels: [UILabel] = [UILabel]()
    
    // MARK: - 构造函数
    init(frame: CGRect, titles: [String], style: DZYPageStyle) {
        self.titles = titles
        self.style = style
        super.init(frame: frame)
 
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: - 设置UI
extension DZYTitleView {
    fileprivate func setupUI() {
        // 1.添加scrollView
        addSubview(scrollView)
        // 2.初始化所有的label
        setupTitleLabels()
        // 3.初始化底部line
        if style.isShowBottonLine {
            setupBottomLine()
        }
        // 4.初始化遮盖view
        if style.isShowCover {
            setupCoverView()
        }
    }
    
    private func setupCoverView() {
        scrollView.insertSubview(coverView, at: 0)
        
        guard let firstLabel = titleLabels.first else { return }
        
        var coverW: CGFloat = firstLabel.frame.width
        let coverH: CGFloat = style.coverViewHeight
        var coverX: CGFloat = firstLabel.frame.origin.x
        let coverY: CGFloat = (firstLabel.frame.height - coverH) * 0.5
        
        if style.isScrollEnabel {
            coverX -= style.coverViewMargin
            coverW += style.coverViewMargin * 2
        }
        
        coverView.frame = CGRect(x: coverX, y: coverY, width: coverW, height: coverH)
        
        coverView.layer.cornerRadius = style.coverViewRadius
        coverView.layer.masksToBounds = true
    
    }
    
    private func setupBottomLine() {
        scrollView.addSubview(bottomLine)
        bottomLine.frame = titleLabels.first!.frame
        bottomLine.frame.size.height = style.bottomLineHeight
        bottomLine.frame.origin.y = style.titleHeight - style.bottomLineHeight
    }

    private func setupTitleLabels() {
        
        // 1. 创建lables
        
        for (i , title) in titles.enumerated() {
            // 1.创建label
            let titleLabel = UILabel()
            
            // 2.设置label的属性
            titleLabel.text = title
            titleLabel.tag = i
            titleLabel.textAlignment = .center
            titleLabel.textColor = i == 0 ? style.selectColor : style.normalColor
            titleLabel.font = style.titleFont
            titleLabel.isUserInteractionEnabled = true
            // 3.将label添加到scrollView上
            scrollView.addSubview(titleLabel)
            
            // 4.监听label的点击
            let tapGes = UITapGestureRecognizer(target: self, action:#selector(titleLabelClick(tapGes:)))
            titleLabel.addGestureRecognizer(tapGes)
            
            // 5,将label添加到数组中
            titleLabels.append(titleLabel)
        }
        
        // 2.设置label的frame
        let labelH: CGFloat = style.titleHeight
        let labelY: CGFloat = 0
        var labelW: CGFloat = bounds.width / CGFloat(titles.count)
        var labelX: CGFloat = 0
        
        for (i, titleLabel) in titleLabels.enumerated() {
            if style.isScrollEnabel { // 可以滚动
                labelW = (titleLabel.text! as NSString).boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: 0), options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: style.titleFont], context: nil).width
                labelX = i == 0 ? style.titleMargin : (titleLabels[i - 1].frame.maxX + style.titleMargin)
                
            } else { // 不能滚动
                labelX = labelW * CGFloat(i)
            }
            titleLabel.frame = CGRect(x: labelX, y: labelY, width: labelW, height: labelH)
        }
        
        // 3. 设置contentSize
        if style.isScrollEnabel {
            scrollView.contentSize = CGSize(width: titleLabels.last!.frame.maxX + style.titleMargin, height: 0)
        }
        
        // 4.设置缩放
        if style.isNeedScale {
            titleLabels.first?.transform = CGAffineTransform(scaleX: style.maxScale, y: style.maxScale)
        }
    }
}

// MARK: - 点击事件
extension DZYTitleView {
    
    func titleLabelClick(tapGes: UITapGestureRecognizer) {
        
        // 0.校验label是否有值
        guard let targetLabel = tapGes.view as? UILabel else {
            return
        }
        
        // 1.判断是否是之前点击的label
        guard targetLabel.tag != currentIndex else {
            return
        }
        
        // 2.通知代理
        // 可选链: 如果可选类型有值 则执行代码 如果没有 什么事情都不发生
        delegate?.titleView(self, targetIndex: targetLabel.tag)
        
        // 3.调整targetLabel
        adjustTitles(targetLabel)
        
    }
    
    // MARK: - 代码抽取1
    fileprivate func adjustTitles(_ targetLabel: UILabel) {
        // 1.让之前的label不选中, 让新的label可以选中
        let sourceLabel = titleLabels[currentIndex];
        sourceLabel.textColor = style.normalColor
        targetLabel.textColor = style.selectColor
        
        // 2.让新的tag作为currentIndex
        currentIndex = targetLabel.tag
        
        // 3.调整点击的label的位置 滚动到中间去
        adjustLabelPosition()
     
        // 4.调整文字缩放
        if style.isNeedScale {
            UIView.animate(withDuration: 0.25, animations: {
                sourceLabel.transform = CGAffineTransform.identity
                targetLabel.transform = CGAffineTransform(scaleX: self.style.maxScale, y: self.style.maxScale)
            })
        }
        
        // 5.调整bottomLine位置
        if style.isShowBottonLine {
            
            UIView.animate(withDuration: 0.25, animations: {
                self.bottomLine.frame.origin.x = targetLabel.frame.origin.x
                self.bottomLine.frame.size.width = targetLabel.frame.width
            })
        }
        
        // 6.调整coverView位置
        if style.isShowCover {
            UIView.animate(withDuration: 0.25, animations: {
                self.coverView.frame.origin.x = self.style.isScrollEnabel ? (targetLabel.frame.origin.x - self.style.coverViewMargin) : targetLabel.frame.origin.x
                self.coverView.frame.size.width = self.style.isScrollEnabel ? (targetLabel.frame.width + self.style.coverViewMargin * 2) : targetLabel.frame.width
            })
        }

    }
    
    // MARK: - 代码抽取2
    fileprivate func adjustLabelPosition() {
        
        guard style.isScrollEnabel else {
            return
        }
        
        let targetLabel = titleLabels[currentIndex]
        
        var offsetX = targetLabel.center.x - scrollView.bounds.width / 2
        
        if offsetX < 0 { // 左
            offsetX = 0
        }
        
        let maxOffsetX = scrollView.contentSize.width - scrollView.bounds.width
        
        if offsetX > maxOffsetX { // 右
            offsetX = maxOffsetX
        }
        
        scrollView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: true)

    }
    
}

// MARK: - 暴露一个属性 方便外界设置
extension DZYTitleView {
    
    func setCurrentIndex(_ index: Int) {
        
        // 1.取出targetLabel
        let targetLabel = titleLabels[index]
        
        // 2. 调整title
        adjustTitles(targetLabel)
    }
}

// MARK: - DZYContentViewDelegate
extension DZYTitleView: DZYContentViewDelegate {
    
    func contentView(_ contentView: DZYContentView, didEndScroll inIndex: Int) {
        
        currentIndex = inIndex
        adjustLabelPosition()
    }
    
    func contentView(_ contentView: DZYContentView, soureIndex: Int, targetIndex: Int, progress: CGFloat) {
        // 1.根据soureIndex和targetIndex获取对应的label
        let sourceLabel = titleLabels[soureIndex]
        let targetLabel = titleLabels[targetIndex]
        
        // 2.颜色渐变
        sourceLabel.textColor = UIColor(r: selectRGB.0 - deltaRGB.0 * progress, g: selectRGB.1 - deltaRGB.1 * progress, b: selectRGB.2 - deltaRGB.2 * progress)
        targetLabel.textColor = UIColor(r: normalRGB.0 + deltaRGB.0 * progress, g: normalRGB.1 + deltaRGB.1 * progress, b: normalRGB.2 + deltaRGB.2 * progress)
        
        // 3..缩放的变化 <缩放会改变frame 最好是放在改变frame的前面>
        if style.isNeedScale {
            let deltaScale = style.maxScale - 1.0
            sourceLabel.transform = CGAffineTransform(scaleX: style.maxScale - deltaScale * progress, y: style.maxScale - deltaScale * progress)
            targetLabel.transform = CGAffineTransform(scaleX: 1.0 + deltaScale * progress, y: 1.0 + deltaScale * progress)
        }
        
        // 4..计算bottomLine的width/x的变化
        let deltaWidth = targetLabel.frame.width - sourceLabel.frame.width
        let deltaX = targetLabel.frame.origin.x - sourceLabel.frame.origin.x
        if style.isShowBottonLine {
            bottomLine.frame.size.width = deltaWidth * progress + sourceLabel.frame.width
            bottomLine.frame.origin.x = deltaX * progress + sourceLabel.frame.origin.x
        }
        
        // 5.coverView的渐变
        if style.isShowCover {
            coverView.frame.origin.x = style.isScrollEnabel ? (sourceLabel.frame.origin.x - style.coverViewMargin + deltaX * progress) : (sourceLabel.frame.origin.x + deltaX * progress)
            coverView.frame.size.width = style.isScrollEnabel ? (sourceLabel.frame.width + style.coverViewMargin * 2 + deltaWidth * progress) : (sourceLabel.frame.width + deltaWidth * progress)
        }

    }
}


